import datetime

# 分类
CATGORY = {
    '电子': {'ipad', 'iphone', '显示器', '笔记本电脑', '键盘'},
    '食品': {'面包', '饼干', '蛋糕', '牛肉', '鱼', '蔬菜'},
    '日用品': {'餐巾纸', '收纳箱', '咖啡杯', '雨伞'},
    '酒类': {'啤酒', '白酒', '伏特加'}
}

# 折扣
DISCOUNT = {
    (11, 11): {'电子': 0.7},  # (月,日): [('品类',折扣)]
    (5, 1): {'日用品': 0.7},
    (5, 2): {'日用品': 0.7},
    (5, 3): {'日用品': 0.7}
}

# 优惠券
COUPON = {('2014.3.2', 1000, 200)}


# 分类
class Catgory():
    cat = None

    def __init__(self, cat):
        self.cat = cat

    # 根据二级分类获取一级分类
    def get_cat_label_by_name(self, name):
        """
        :param name: String
        :return:
        """
        for k, v in self.cat.items():
            if name in v:
                return k
        return None


# 折扣
class Discount():
    discount = None

    def __init__(self, data):
        self.discount = data

    def get_rate_by_date_cat(self, date, cat):
        """
        :param date: (11,11)  (月,日)
        :param cat: String
        :return: rate or None
        """
        the_date_rate = self.discount.get(date, None)
        if the_date_rate and the_date_rate.get(cat, None):
            return the_date_rate.get(cat)
        else:
            return None


# 优惠券
class Coupon():
    coupon = None

    def __init__(self, data):
        self.coupon = data

    def verify_coupon(self, coupon):
        """
        验证优惠券是否存在
        :param coupon: type: tuple eg: ('2014.3.2', 1000, 200)
        :return: True or False
        """
        return coupon in self.coupon


# 订单用例
class Case():
    discount_cat = None  # 折扣分类  type: string
    discount = None  # 折扣  type: float
    order_date = None  # 下单日期  type: date
    pay_date = None  # 支付日期  type: date
    goods = []  # 商品列表 [{cat:'ipad', 'price':2399.00, 'count':1}]
    coupon = None  # 优惠券('2014.3.2','1000','200')

    def __init__(self, file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
            if lines[-1].endswith('\n'):
                lines.append('')
            for index, line in enumerate(lines):
                lines[index] = line.replace('\n', '')
        self.parse_case(lines)

    # 解析case内容
    def parse_case(self, lines):
        if lines[0].replace(' ', '') == '':  # 头行为空
            header = None
            body = lines[1:-3]
            footer = lines[-2:]
        else:
            header = lines[0]
            body = lines[2:-3]
            footer = lines[-2:]

        if header:
            s = header.replace(' ', '')
            s_l = s.split('|')
            self.order_date = datetime.datetime.strptime(s_l[0], '%Y.%m.%d').date()
            self.discount = float(s_l[1])
            self.discount_cat = s_l[2]

        for line in body:
            line = line.replace(' ', '')
            line = line.replace('*', ':')
            count_cat_price = line.split(':')
            goods_date = {
                'count': int(count_cat_price[0]),
                'cat': count_cat_price[1],
                'price': float(count_cat_price[2])
            }
            self.goods.append(goods_date)

        self.pay_date = datetime.datetime.strptime(footer[0], '%Y.%m.%d').date()
        if footer[1]:
            coupon = tuple(footer[1].split(' '))
            self.coupon = (coupon[0], int(coupon[1]), int(coupon[2]))


class Order():
    catgory = None
    discount = None
    coupon = None
    case = None
    amount = 0

    def __init__(self, catgory, discount, coupon, case):
        self.catgory = catgory
        self.discount = discount
        self.coupon = coupon
        self.case = case

    # 验证折扣
    def verify_discount(self):
        if self.case.discount:
            date = (self.case.pay_date.month, self.case.pay_date.day)
            cat = self.case.discount_cat
            res = self.case.discount == self.discount.get_rate_by_date_cat(date, cat)
            return res
        return True

    # 验证优惠券
    def verify_coupon(self):
        if self.case.coupon:
            return self.coupon.verify_coupon(self.case.coupon)
        return True

    # 验证订单
    def verify(self):
        res = (self.verify_discount(), self.verify_coupon())
        if all(res):
            return True
        return False

    # 计算总价
    def get_amount(self):
        for g in self.case.goods:
            if self.case.discount_cat and self.catgory.get_cat_label_by_name(g['cat']) == self.case.discount_cat:
                self.amount += g['price'] * g['count'] * self.case.discount
            else:
                self.amount += g['price'] * g['count']
        if self.case.coupon and self.amount >= self.case.coupon[1]:
            self.amount -= self.case.coupon[2]
        return round(self.amount, 2)


if __name__ == '__main__':
    catgory_obj = Catgory(CATGORY)
    discount_obj = Discount(DISCOUNT)
    coupon_obj = Coupon(COUPON)
    # case_obj = Case('/Users/mac/PycharmProjects/syl_1912/test/case/A.case')
    case_obj = Case('/Users/mac/PycharmProjects/syl_1912/test/case/B.case')

    order_obj = Order(catgory_obj, discount_obj, coupon_obj, case_obj)

    if order_obj.verify():
        print(order_obj.get_amount())
    else:
        print('订单有问题')
